home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Day Cry
/
Day Cry CD.bin
/
oh_towns
/
taropyon
/
splib
/
splib.lzh
/
PRG
/
LHX
/
EXTRACT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-08
|
7KB
|
340 lines
/***********************************************************
extract.c -- extract file from archive
***********************************************************/
#include "lh386.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <io.h>
#include <dos.h>
#include <direct.h>
#include "lh.h"
#include "intrface.h"
#include "errmes.h"
#include <fslib.h>
#ifdef __HIGHC__
# pragma On(Align_labels);
#endif
/* #define EX_DEBUG */
extern boolean verify_mode;
static char methods[10][5] =
{
"-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-",
"-lh5-", "-lzs-", "-lz5-", "-lz4-", "\0\0\0\0\0"
};
static void skipdisp(char *mes)
{
LHX_fprintf(stderr, "Skipped %-12s : %s\n", hpb.filename, mes);
}
/*******************************
test the file name which
should be melted
*******************************/
static char tstdir(char *name)
{
char *p, *q, yn;
int absent;
struct find_t srchbuf;
p = name;
if (*p && p[1] == ':') /* skip a drive name */
p += 2;
if (*p == DELIM) /* skip a root mark('\') */
p++;
yn = flg_m ? 'Y' : 'N';
q = p;
while ((p = strchr(p, DELIM)) != NULL)
{ /* skip to next '\' */
if (*q != '.')
{
*p = '\0';
absent = _dos_findfirst(name, 0x17, &srchbuf);
if (absent)
{
if (yn == 'N')
{
*p = DELIM;
LHX_fprintf(stderr, "'%s' : %s", name, MKDIR);
*p = '\0';
yn = getyn();
}
if (yn == 'N')
{
return 'S';
} else
{
if (makedir(name))
{ /* make directory */
error(MKDIRERR, name);
}
}
} else
{
if ((srchbuf.attrib & 0x10) == 0)
{
error(MKDIRERR, name); /* if the name isn't
* directory */
}
}
*p = DELIM;
}
q = ++p;
}
if (!_dos_findfirst(name, 0x17, &srchbuf))
{
/* already exists */
if (flg_c == 0 &&
dos2unix((struct ftime *) & srchbuf.wr_time) >= hpb.utc)
yn = 'S';
switch (flg_m)
{
case 0:
if (yn != 'S')
{
LHX_fprintf(stderr, "'%s' %s", name, OVERWT);
yn = (getyn() == 'Y') ? 'O' : 'S';
break;
}
case 1:
if (yn == 'S')
{
skipdisp(NEWFILE);
break;
}
yn = 'O';
break;
case 2:
yn = 'R';
break;
}
if (yn != 'O')
{
return yn;
}
if (srchbuf.attrib & 0x01 &&
srchbuf.attrib != hpb.attr && flg_a)
{
/* if the file is read-only, */
/* attributes must match */
skipdisp(RDONLY);
return 'S';
}
if (srchbuf.attrib & 0x10)
{
skipdisp(SAMEDIR);
return 'S';
}
if (srchbuf.attrib & 0x07)
_dos_setfileattr(name, 0x20); /* reset attributes */
}
return 'O';
}
static int rename_ext(char *name)
{
int i;
char *p, *q;
struct find_t srchbuf;
p = strrchr(name, '.');
q = strrchr(name, DELIM);
if (p <= q)
p = name + strlen(name);
for (i = 0; i <= 999; i++)
{
sprintf(p, ".%03d", i);
if (_dos_findfirst(name, 0x17, &srchbuf))
return 1;
}
return 0;
}
static void print_ing( CONST char *name )
{
LHX_fprintf( stderr, "\r%-12s - Printing\n\n", name );
}
static char _TESTING_[] = "Testing ";
static char _MELTING_[] = "Melting ";
void extract(char *bdir)
{
char *path;
int method, handle;
memcpy(methods[9], hpb.method, 5);
for (method = 0; memcmp(hpb.method, methods[method], 5); method++)
;
if (method == 9)
{
skipdisp(METHODERR);
return;
}
switch (cmd)
{
case 'E':
form_path(hpb.pathname);
hpb.filename = getfilename(hpb.pathname);
path = (flg_x) ? hpb.pathname : hpb.filename;
strcpy(filename3, bdir);
if (*(unsigned char *) path == DELIM)
{
if (filename3[1] == ':')
{
filename3[2] = '\0';
} else
{
*filename3 = '\0';
}
}
strcat(filename3, path);
{
int ret;
ret = tstdir(filename3);
switch (ret)
{
case 'R':
if (rename_ext(filename3))
break;
skipdisp(NOMOREEXT);
case 'S':
return;
}
}
{
long dskfree;
dskfree = diskspace(filename3);
if (dskfree < hpb.original)
{
skipdisp(DISKFULL);
return;
}
}
file3 = mywopen(filename3);
LHX_fprintf(stderr, "Melting ");
LHX_printf("%-12s ", getfilename(path));
break;
case 'P':
#ifndef CAN_NOT_USE_FDOPEN
handle = fileno(stdout);
flg_n |= isatty(handle);
if (flg_n == 0)
LHX_fprintf(stderr, "Melting ");
file3 = fdopen(dup(handle), "wb");
LHX_fprintf(file3, "\r\n<< %s >>\r\n\r\n", hpb.filename);
#else
file3 = stdout;
#endif
break;
case 'T':
if (hpb.level < 0)
{
skipdisp(NOCRC);
return;
}
file3 = NULL;
break;
}
interface.method = method;
interface.dicbit = 13; /* method + 8; */
interface.infile = file1;
interface.outfile = file3;
interface.original = hpb.original;
interface.packed = hpb.packed;
interface.dispflg = flg_n;
switch (method)
{
case 0:
case 8:
if ( cmd == 'P' )
{ print_ing( hpb.filename );
} else
{ start_indicator(hpb.filename, interface.original
,verify_mode ? _TESTING_ : _MELTING_, 2048);
}
copyfile(file1, file3, hpb.original, 1);
break;
case 6:
interface.dicbit = 11;
if ( cmd == 'P' )
{ print_ing( hpb.filename );
} else
{ start_indicator(hpb.filename, interface.original
,verify_mode ? _TESTING_ : _MELTING_
,1 << interface.dicbit);
}
decode(&interface);
break;
case 1:
case 4:
case 7:
interface.dicbit = 12;
default:
if ( cmd == 'P' )
{ print_ing( hpb.filename );
} else
{ start_indicator(hpb.filename, interface.original
,verify_mode ? _TESTING_ : _MELTING_
,1 << interface.dicbit);
}
decode(&interface);
}
if ( (file3 != stdout && file3 != stderr) && file3 )
{
fflush(file3);
setfiletime(file3, hpb.utc);
fclose(file3);
file3 = NULL;
}
if (hpb.level >= 0 && crc != hpb.filecrc)
{
errorlevel = 1;
LHX_fprintf(stderr, "\rCRC err\n");
if (cmd == 'E')
{
if (flg_m == 0)
{
LHX_fprintf(stderr, " delete(y/n)? ");
if (getyn() == 'Y')
FS_remove(filename3);
} else
{
FS_remove(filename3);
}
}
if (flg_m == 0)
{
LHX_fprintf(stderr, " continue(y/n)? ");
if (getyn() != 'Y')
error(CTRLBRK, NULL);
}
} else
{
if ( cmd == 'P' )
LHX_putc('\n');
else
finish_indicator( hpb.filename, verify_mode ? "Tested " : "Melted ");
if (cmd == 'E' && flg_a)
_dos_setfileattr(filename3, hpb.attr);
}
}
void dispusage(void)
{
LHX_puts(use); /* stdout */
MAIN_EXIT(2);
}